﻿using System;
using System.Net;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Threading.Tasks;

namespace TaskCompletionSourceUser
{
	/// <summary>
	/// This us only particularly usefull when working with restful services in Silverlight,
	/// but is is still a good illustration of the task completion source.
	/// the WebClient now has the ability to "DownloadStringTaskAsync" so you can use tasks directly 
	/// from the webclient.  The new webclient is not available in silverlight.
	/// </summary>
	public class JSONServiceProxy
	{
		private string _baseURL;

		public JSONServiceProxy(string location)
		{
			_baseURL = location;
		}

		public Task<T> GetObject<T>(string resourcePath)
		{
			WebClient client = new WebClient();
			client.Encoding = Encoding.UTF8;
			client.Headers.Add("Content-Type", "application/json");
			var tcs = new TaskCompletionSource<T>(resourcePath, TaskCreationOptions.None);
			var handler = new OpenReadCompletedEventHandler((object sender, OpenReadCompletedEventArgs e) =>
			{
				if (e.UserState == tcs)
				{
					if (e.Cancelled)
						tcs.TrySetCanceled();
					else if (e.Error != null)
						tcs.TrySetException(e.Error);
					else
					{
						DataContractJsonSerializer cereal = new DataContractJsonSerializer(typeof(T));
						tcs.TrySetResult((T)cereal.ReadObject(e.Result));
					}
				}
			});

			client.OpenReadCompleted += handler;
			try
			{
				client.OpenReadAsync(new Uri(string.Concat(_baseURL, resourcePath)), tcs);
			}
			catch (Exception e)
			{
				client.OpenReadCompleted -= handler;
				tcs.TrySetCanceled();
				throw e;
			}

			return tcs.Task;
		}

	}
}
